﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include    <QTreeWidgetItem>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initStatusBar();
    initTreeHeader();
    initTree();
    //设置控件中间位置
    setCentralWidget(ui->scrollArea);
    //相关action控件设置setenable不显示
}

MainWindow::~MainWindow()
{
    delete ui;

}
//主要练习一个自适应滚动条，action，以及treeWidget
//在statusbar上增加相关控件
void MainWindow::initStatusBar()
{
    m_labNodeText = new QLabel("节点标题",this);
    m_spinRatio = new QSpinBox(this);
    m_labFileName = new QLabel("文件名",this);

    m_labNodeText->setMaximumWidth(300);
    ui->m_statusbar->addWidget(m_labNodeText);

    m_spinRatio->setMaximumWidth(300);
    m_spinRatio->setRange(0,2000);
    m_spinRatio->setValue(100);
    m_spinRatio->setSuffix(" %");
    m_spinRatio->setReadOnly(true);
    m_spinRatio->setButtonSymbols(QAbstractSpinBox::NoButtons);
    ui->m_statusbar->addPermanentWidget(m_spinRatio);

    ui->m_statusbar->addPermanentWidget(m_labFileName);
}

void MainWindow::initTreeHeader()
{
    ui->m_treeWidget->clear(); //清除节点内容  不改变头部信息
    ui->m_treeWidget->setColumnWidth(MainWindow::colItem, 150); //简单设置第一列列宽
    QTreeWidgetItem * header = new QTreeWidgetItem();

    header->setText(MainWindow::colItem,     "目录和文件");
    header->setText(MainWindow::colItemType, "节点类型");
    header->setBackground(MainWindow::colItem, QBrush(Qt::red));
    header->setText(MainWindow::colDate,     "最后修改日期");
    header->setTextAlignment(colItem,       Qt::AlignHCenter | Qt::AlignVCenter);
    header->setTextAlignment(colItemType,   Qt::AlignHCenter | Qt::AlignVCenter);
    ui->m_treeWidget->setHeaderItem(header);
}

//设置一个样例 头结点信息
void MainWindow::initTree()
{
    QIcon  icon(":/images/icons/15.ico");

    QTreeWidgetItem*  item=new QTreeWidgetItem(MainWindow::itTopItem); //节点类型为itTopItem
    item->setIcon(MainWindow::colItem,icon);          //设置第1列的图标
    item->setText(MainWindow::colItem, "图片");       //设置第1列的文字
    item->setText(MainWindow::colItemType, "Top Item");     //设置第2列的文字
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    item->setCheckState(MainWindow::colItem, Qt::Checked);  //设置为选中
    //可以存储角色和数据  然后后面通过该项进行取出
    item->setData(MainWindow::colItem,Qt::UserRole,QVariant(123));
    ui->m_treeWidget->addTopLevelItem(item);//添加顶层节点
}

//相关的树节点控件的增删改查

//相关控件的回调 节点变化时，需要做相关的显示
void MainWindow::on_m_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
    if(current == nullptr)
        return;
    if(current == previous)
        return;  //节点没有切换变化

    //这里通过区分节点的类型  进行不同的处理
    int var = current->type();
    switch(var)
    {
    case itTopItem:
        ui->actAddFolder->setEnabled(true);
        ui->actAddFiles->setEnabled(true);
        ui->actDeleteItem->setEnabled(false);
        break;
    case itGroupItem:
        ui->actAddFolder->setEnabled(true);
        ui->actAddFiles->setEnabled(true);
        ui->actDeleteItem->setEnabled(false);
        break;
    case itImageItem:
        ui->actAddFolder->setEnabled(false);
        ui->actAddFiles->setEnabled(true);
        ui->actDeleteItem->setEnabled(true);
        displayImage(current);
        break;
    }
}
#include <QFileDialog>
//这里必须选择节点位置才能进行插入节点  在选中节点位置下面进行插入
void MainWindow::on_actAddFolder_triggered()
{
    QString dir = QFileDialog::getExistingDirectory();
    if(dir.isEmpty())
        return;

    QTreeWidgetItem *parent = ui->m_treeWidget->currentItem();
    if(parent == nullptr)
//        parent = ui->m_treeWidget->topLevelItem(1); //
        return;
    //只有选中一个节点  在节点下才能添加
    if(parent->type() != itImageItem)
        addFolderItem(parent, dir);
    //这里要过滤所有的图片文件  之后进行子节点的添加 并展开
    //这里其实添加目录后应该触发相关子节点的信息获取及展开
    //    parent->setExpanded(true);
}
#include <QStringList>
void MainWindow::on_actAddFiles_triggered()
{
    QStringList files = QFileDialog::getOpenFileNames(this, "选择文件","","images(*.png *.jpg *.jpeg)");
    if(files.isEmpty())
        return;

    //获取当前节点  进行相关处理
    QTreeWidgetItem * item, *parItem;
    item = ui->m_treeWidget->currentItem();
    if(item ==nullptr)//没有当前节点取顶层节点
    {
        item = ui->m_treeWidget->topLevelItem(0);
    }

    if(item->type() == itImageItem)
        parItem = item->parent();
    else
        parItem = item;

    //然后再parItem下新增相关文件
    for(int i=0; i<files.size(); i++)
    {
        QString aFileName = files.at(i);
        addImageItem(parItem, aFileName);
    }
    parItem->setExpanded(true); //展开这些节点
}

void MainWindow::on_actZoomIn_triggered()
{
    m_ratio=m_ratio*1.2;
    m_spinRatio->setValue(100*m_ratio);

    int w=m_ratio*m_pixmap.width();   //显示宽度
    int h=m_ratio*m_pixmap.height();  //显示高度

    QPixmap pix = m_pixmap.scaled(w, h);
    ui->m_LabPic->setPixmap(pix);
}

void MainWindow::on_actZoomOut_triggered()
{
    m_ratio=m_ratio*0.8;
    m_spinRatio->setValue(100*m_ratio);

    int w=m_ratio*m_pixmap.width();   //显示宽度
    int h=m_ratio*m_pixmap.height();  //显示高度

    QPixmap pix = m_pixmap.scaled(w, h);
    ui->m_LabPic->setPixmap(pix);
}

void MainWindow::on_actZoomRealSize_triggered()
{
    m_ratio=1;
    m_spinRatio->setValue(100);
    ui->m_LabPic->setPixmap(m_pixmap);
}

void MainWindow::on_actZoomFitW_triggered()
{
    int w=ui->scrollArea->width()-20;   //得到scrollArea的高度
    int realw=m_pixmap.width();        //原始图片的实际宽度
    m_ratio=float(w)/realw;            //当前显示比例，必须转换为浮点数

    m_spinRatio->setValue(m_ratio*100);

    QPixmap pix=m_pixmap.scaledToWidth(w-30);
    ui->m_LabPic->setPixmap(pix);
}

void MainWindow::on_actZoomFitH_triggered()
{
    int H= ui->scrollArea->height();
    int realH = m_pixmap.height();
    m_ratio = float(H)/realH;

    m_spinRatio->setValue(100 *m_ratio);

    QPixmap pix = m_pixmap.scaledToHeight(H-30);
    ui->m_LabPic->setPixmap(pix);
}

void MainWindow::on_actDeleteItem_triggered()
{
    QTreeWidgetItem *item = ui->m_treeWidget->currentItem();
    if(item == nullptr) return;
    QTreeWidgetItem *parItem = item->parent();
    delItem(parItem, item);
}

//遍历节点
void MainWindow::on_actScanItems_triggered()
{
    for(int i=0; i<ui->m_treeWidget->topLevelItemCount(); i++)
    {
        QTreeWidgetItem *item = ui->m_treeWidget->topLevelItem(i);
        changeItemCaption(item);
    }
}

//悬浮窗口相关的槽函数 以及对应action控制
void MainWindow::on_dockWidget_visibilityChanged(bool visible)
{
    ui->actDockVisable->setChecked(visible);
}

void MainWindow::on_dockWidget_topLevelChanged(bool topLevel)
{
    ui->actDockFloat->setChecked(topLevel);
}

void MainWindow::on_actDockVisable_triggered(bool checked)
{
    ui->dockWidget->setVisible(checked);
}

void MainWindow::on_actDockFloat_triggered(bool checked)
{
    ui->dockWidget->setFloating(checked);
}

//这里其他 需要研究QTreewidget相关的槽函数
void MainWindow::on_m_treeWidget_itemChanged(QTreeWidgetItem *item, int column)
{
    Q_UNUSED(item);
    Q_UNUSED(column);
    qDebug("itemChanged() is emitted");
}

//在非图片节点处  可以新增一个树节点
void MainWindow::addFolderItem(QTreeWidgetItem* paritem, QString DirName)
{
    QString str = getRealFolderName(DirName);
    QIcon   icon(":/images/icons/open3.bmp");
    QTreeWidgetItem *item = new QTreeWidgetItem(MainWindow::itGroupItem);
    item->setIcon(colItem, icon);
    item->setText(colItem, str);
    item->setText(colItemType,"Group Item");
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                   | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    item->setCheckState(colItem,Qt::Checked); //节点选中
    item->setData(colItem, Qt::UserRole,QVariant(DirName));//保存完整路径  后面展现用
    paritem->addChild(item);
}

QString MainWindow::getRealFolderName(QString DirName)
{
    int cnt = DirName.length();
    int i = DirName.lastIndexOf("/");
    QString str = DirName.right(cnt-i-1);
    return str;
}

//在父节点的基础下 创建一个节点
#include <QFileInfo>
#include <QDateTime>
void MainWindow::addImageItem(QTreeWidgetItem* paritem, QString aFileName)
{
    //QFileInfo获取文件信息
    QIcon   icon(":/images/icons/31.ico");
    QFileInfo fileInfo(aFileName);      //QFileInfo对象
    QString NodeText=fileInfo.fileName();          //不带路径的文件名
    QDateTime birthDate=fileInfo.lastModified();   //文件的创建日期
    //识别树的根目录及其他目录  都是依赖这里设置的节点类型
    QTreeWidgetItem *aitem = new QTreeWidgetItem(MainWindow::itImageItem);
    aitem->setIcon(colItem, icon);
    aitem->setText(colItem, NodeText);
    aitem->setText(colItemType,"Image Item");
    aitem->setText(colDate,birthDate.toString("yyyy-MM-dd"));
    aitem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                    | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    aitem->setCheckState(colItem, Qt::Checked);

    aitem->setData(colItem,Qt::UserRole,QVariant(aFileName));
    paritem->addChild(aitem);
}

void MainWindow::displayImage(QTreeWidgetItem* current)
{
    QString filename = current->data(colItem,Qt::UserRole).toString();
    m_labFileName->setText(filename);
    m_labNodeText->setText(current->text(colItem));

    m_pixmap.load(filename);
    ui->actZoomFitH->trigger();

    ui->actZoomIn->setEnabled(true);
    ui->actZoomOut->setEnabled(true);
    ui->actZoomFitH->setEnabled(true);
    ui->actZoomFitW->setEnabled(true);
    ui->actZoomRealSize->setEnabled(true);
}

void MainWindow::delItem(QTreeWidgetItem *parItem, QTreeWidgetItem *item)
{
    if(item->childCount()>0)
    {
        int count = item->childCount();
        QTreeWidgetItem *temp = item;
        for(int i=count-1; i>=0; i--)
        {
            delItem(temp, temp->child(i));
        }
    }

    parItem->removeChild(item);
    delete item;
}

//只是演示  没有实际作用
void MainWindow::changeItemCaption(QTreeWidgetItem* item)
{
    QString str = "*"+item->text(colItem); //只处理第一列
    item->setText(colItem, str);

    if(item->childCount()>0)
    {
        for(int i=0; i<item->childCount(); i++)
        {
            changeItemCaption(item->child(i));
        }
    }
}

/*
    itemClicked(QTreeWidgetItem* item, int column)：
        当用户点击了树形控件中的某个项时触发。参数item表示被点击的项，column表示被点击项所在的列。
    itemDoubleClicked(QTreeWidgetItem* item, int column)：
        当用户双击了树形控件中的某个项时触发。参数item表示被双击的项，column表示被双击项所在的列。
    currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)：
        当当前选中项改变时触发。参数current表示新选中的项，previous表示之前选中的项。
    itemExpanded(QTreeWidgetItem* item)：
        当某个项展开时触发。参数item表示被展开的项。
    itemCollapsed(QTreeWidgetItem* item)：当
        某个项折叠起来时触发。参数item表示被折叠的项。
    headerClicked(int logicalIndex)：
        当表头被点击时触发。参数logicalIndex表示表头列索引。
    currentTextChanged(const QString& text)：
        当当前选中项文本内容改变时触发。参数text为新选中项文本内容。
    customContextMenuRequested(const QPoint& pos)：
        当右键菜单请求事件发生时触发该槽函数。参数pos表示鼠标点击的位置。
    itemChanged(QTreeWidgetItem* item, int column)：
        当树形控件中的项发生变化时触发。参数item表示发生变化的项，column表示发生变化项所在的列。
    itemActivated(QTreeWidgetItem* item, int column)：
        当某个项被激活（例如双击或回车键）时触发。参数item表示被激活的项，column表示被激活项所在的列。
    itemSelectionChanged()：
        当选择的项集合发生变化时触发，可以通过selectedItems()获取当前选中的所有项。
    itemPressed(QTreeWidgetItem* item, int column)
        按下某个项时触发。参数item表示被按下的项，column表示被按下项所在的列。
*/